#ifndef _IOEVDEF_H_
#define _IOEVDEF_H_

#include "crt_util.h"

#define IOEVTCP_OK      0
#define IOEVTCP_SUCCESS 0x00
#define IOEVTCP_ERROR   0x01

#define IOEV_NOTIFY_TYPE_WORK 1
#define IOEV_NOTIFY_TYPE_EXIT 0

typedef struct ioevloop_s ioevloop_t;
typedef int (*evloop_notify)(ioevloop_t* evloop, int index);
struct ioevloop_s {
    void* ctx;
    evloop_notify notify;
};

int ioevloop_setnotify(ioevloop_t* loop, evloop_notify cb);
int ioevloop_setctx(ioevloop_t* loop, void* ctx);
void* ioevloop_getctx(ioevloop_t* loop);

typedef struct ioevtcp_s ioevtcp_t;
typedef int (*tcp_eventcb)(ioevtcp_t* tcp, short err);
typedef int (*tcp_acceptcb)(ioevtcp_t* tcp, SOCKADDR_PTR sa, socklen_t sl, _sock_t sock);
struct ioevtcp_s {
    void* ctx;
    tcp_eventcb event;
    tcp_acceptcb accept;
};

int ioevtcp_init(ioevtcp_t* tcp, ioevloop_t* evloop, _sock_t sock);
int ioevtcp_uninit(ioevtcp_t* tcp);
int ioevtcp_setctx(ioevtcp_t* tcp, void* ctx);
void* ioevtcp_getctx(ioevtcp_t* tcp);
int ioevtcp_seteventcb(ioevtcp_t* tcp, tcp_eventcb cb);
int ioevtcp_setacceptcb(ioevtcp_t* tcp, tcp_acceptcb cb);
int ioevtcp_bind(ioevtcp_t* tcp, NET_ADDR ip, NET_ADDR_PORT port);
int ioevtcp_bind6(ioevtcp_t* tcp, NET_ADDR ip, NET_ADDR_PORT port);
int ioevtcp_enable(ioevtcp_t* tcp);
int ioevtcp_disable(ioevtcp_t* tcp);

#define IOEV_STREAM_EOF   0x00
#define IOEV_STREAM_OPEN  0x01
#define IOEV_STREAM_ERROR 0x02
#define IOEV_STREAM_WRITE 0x04
#define IOEV_STREAM_READ  0x08
#define IOEV_STREAM_TMOUT 0x10

#define IOEVSTREAM_OPEN    0x01
#define IOEVSSLSTREAM_OPEN 0x02

#define IOEV_STREAM_OPTIONS (BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS | BEV_OPT_THREADSAFE)

typedef struct ioevstream_s ioevstream_t;
typedef int (*stream_eventcb)(ioevstream_t* stream, short err, short what, _sock_t fd);
typedef int (*stream_readcb)(ioevstream_t* stream, short err, buf_ptr ptr, buf_len len);
typedef int (*stream_writecb)(ioevstream_t* stream, short err, buf_ptr ptr, buf_len len);
struct ioevstream_s {
    void* ctx;
    stream_eventcb event;
    stream_readcb read;
    stream_writecb write;
};

int ioevstream_init(ioevstream_t* stream, ioevloop_t* evloop, _sock_t sock);
int ioevstream_uninit(ioevstream_t* stream);
int ioevstream_assign(ioevstream_t* stream, _sock_t sock);
int ioevstream_setctx(ioevstream_t* stream, void* ctx);
void* ioevstream_getctx(ioevstream_t* stream);
int ioevstream_seteventcb(ioevstream_t* stream, stream_eventcb cb);
int ioevstream_setreadcb(ioevstream_t* stream, stream_readcb cb);
int ioevstream_setwritecb(ioevstream_t* stream, stream_writecb cb);
int ioevstream_write(ioevstream_t* stream, buf_ptr ptr, buf_len len, int sec);
int ioevstream_read(ioevstream_t* stream, buf_ptr ptr, buf_len len, int sec);
int ioevstream_connectsock(ioevstream_t* stream, NET_ADDR ip, NET_ADDR_PORT port, int sec);
int ioevstream_connect6sock(ioevstream_t* stream, NET_ADDR ip, NET_ADDR_PORT port, int sec);

#endif
